package com.example.yimai.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.yimai.dto.PageResponseDTO;
import com.example.yimai.entity.Product;
import com.example.yimai.mapper.ProductMapper;
import com.example.yimai.repository.ProductRepository;
import com.example.yimai.service.ProductService;
import com.example.yimai.utils.ESUtil;
import com.example.yimai.utils.ParamUtil;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Service
@Slf4j
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService {

    @Autowired
    private ProductRepository productRepository;

    @Autowired
    private ElasticsearchOperations elasticsearchOperations;

    @Override
    public PageResponseDTO<Product> queryProduct(String keyword, int pageNum, int pageSize) {
        try {
            // 构建查询参数
            BoolQueryBuilder params;
            if(keyword == null || keyword.isEmpty())
                params = QueryBuilders.boolQuery();
            else {
                params = QueryBuilders.boolQuery().should(QueryBuilders.matchQuery("name", keyword));
                try{
                    LocalDate date = LocalDate.parse(keyword);
                    params.should(QueryBuilders.matchQuery("createTime", date));
                }catch (Exception e){
                    //忽略
                }
            }
            //构建查询
            NativeSearchQuery query = ESUtil.buildQuery(pageNum, pageSize, params);
            //获取查询结果
            SearchHits<Product> searchHits = elasticsearchOperations.search(query, Product.class);
            //将结果解析为Product数组
            List<Product> products = searchHits.getSearchHits().stream().map(hit ->{
                Product product = hit.getContent();
                return product;
            }).toList();
            //构建返回对象
            PageResponseDTO<Product> results = new PageResponseDTO<>();
            results.setData(products);
            results.setTotal((int)searchHits.getTotalHits());
            results.setPageNum(pageNum + 1);
            results.setPageSize(pageSize);
            return results;
        }catch (Exception e){
            log.info("查询商品数据失败"+e.getMessage());
            throw new RuntimeException("查询商品数据失败"+e.getMessage());
        }

    }

    @Override
    public Product getProduct(Integer id){
        return getById(id);
    }

    @Override
    public String addProduct(Map<String, Object> params) {
        Product product = parseProduct(params);
        try {
            save(product);
            productRepository.save(product);
            return "success";
        }catch (Exception e){
            throw new RuntimeException("添加商品失败"+e.getMessage());
        }
    }

    @Override
    public String deleteProduct(Integer id) {
        try{
            removeById(id);
            productRepository.deleteById(String.valueOf(id));
            return "success";
        }catch (Exception e){
            throw new RuntimeException("删除商品失败"+e.getMessage());
        }
    }

    @Override
    public String updateProduct(Map<String, Object> params) {
        try{
            Product product = parseProduct(params);
            UpdateWrapper<Product> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("id", product.getId());
            update(product, updateWrapper);
            productRepository.save(product);
            return "success";
        }catch (Exception e){
            throw new RuntimeException("更新商品失败"+e.getMessage());
        }
    }

    @Override
    public List<Product> getSameCategoryProducts(String id) {
        try {
            BoolQueryBuilder params = QueryBuilders.boolQuery();
            params.should(QueryBuilders.matchQuery("categoryLevel1Id", id));
            params.should(QueryBuilders.matchQuery("categoryLevel2Id", id));
            params.should(QueryBuilders.matchQuery("categoryLevel3Id", id));

            NativeSearchQuery query = new NativeSearchQuery(params);
            SearchHits<Product> searchHits = elasticsearchOperations.search(query, Product.class);
            List<Product> results = searchHits.getSearchHits().stream().map(hit ->{
                Product product = hit.getContent();
                return product;
            }).toList();
            return results;
        }catch (Exception e){
            throw new RuntimeException("查询同类商品失败"+e.getMessage());
        }
    }

    public Product parseProduct(Map<String, Object> params) {
        Product product = new Product();

        product.setId(ParamUtil.parseParams(params,"id"));
        product.setName(ParamUtil.parseParams(params,"name"));
        product.setDescription(ParamUtil.parseParams(params,"description"));
        product.setPrice(ParamUtil.parseParamsFloat(params,"price"));
        product.setStock(ParamUtil.parseParamsInt(params,"stock"));
        product.setCategoryLevel1Id(ParamUtil.parseParamsInt(params,"categoryLevel1Id"));
        product.setCategoryLevel2Id(ParamUtil.parseParamsInt(params,"categoryLevel2Id"));
        product.setCategoryLevel3Id(ParamUtil.parseParamsInt(params,"categoryLevel3Id"));
        product.setFileName(Objects.toString(ParamUtil.parseParams(params,"fileName"),null));

        return product;
    }

}
